package gosdk

import (
	"gitee.com/youkelike/ziam/zsdk2/gosdk/service/ziam"
	"gitee.com/youkelike/ziam/zsdk2/rest"
)

type Interface interface {
	// 当前接口方法要求返回下一层的接口，但接口方法的实际代码中返回的是下一层的结构体，所以下层结构体必须实现下层接口
	Ziam() ziam.ZiamInterface
	// Tms() tms.TmsInterface
}

// 因为 ziam 的构造方法会返回错误，所以要先实例化后存到字段，否则要打断链式调用来处理错误，
type Clientset struct {
	ziam *ziam.ZiamClient
	// tms *tms.TmsClient
}

// 这一句强制要求必须实现接口，最外层结构体的接口约束利用这种形式，
// 但内层结构体的接口约束通过这 3 步来限定：
//
//	1、本层结构体的字段值是下一层结构体实例，
//	2、本层接口方法实际返回的是字段值，也就是下一层的结构体实例
//	3、本层接口方法定义了返回的应该是下一层的接口
//
// 由此间接限定了下一层的结构体一定要实现下一层的接口
var _ Interface = &Clientset{}

func (c *Clientset) Ziam() ziam.ZiamInterface {
	return c.ziam
}

func NewForConfig(c *rest.Config) (*Clientset, error) {
	// 浅拷贝
	configShallowCopy := *c

	var cs Clientset
	var err error

	// 本层结构体在实例化之前会先把下层结构体实例化，存到字段，
	// 因为下层结构体的构造方法会返回 error，所以要这样做，否则在调用接口方法时就要处理错误，从而打断链式调用
	cs.ziam, err = ziam.NewForConfig(&configShallowCopy)
	if err != nil {
		return nil, err
	}

	/*
		cs.tms, err = tms.NewForConfig(&configShallowCopy)
		if err != nil {
			return nil, err
		}
	*/
	return &cs, nil
}

func NewForConfigOrDie(c *rest.Config) *Clientset {
	var cs Clientset
	cs.ziam = ziam.NewForConfigOrDie(c)
	// cs.tms = tms.NewForConfigOrDie(c)
	return &cs
}

func New(c rest.Interface) *Clientset {
	var cs Clientset
	cs.ziam = ziam.New(c)
	// cs.tms = tms.New(c)
	return &cs
}
